package com.yanqu.road.server.manger.activity.diggold;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.diggold.config.*;
import com.yanqu.road.entity.activity.diggold.data.DigGoldUserData;
import com.yanqu.road.entity.activity.diggold.entity.DigGoldBlockData;
import com.yanqu.road.entity.config.system.NormalWeightItem;
import com.yanqu.road.entity.enums.activity.DigGold.eDigGoldBlockType;
import com.yanqu.road.entity.enums.activity.DigGold.eDigGoldRewardType;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.logic.bussiness.activity.DigGoldBusiness;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.DigGoldProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.diggold.DigGoldModule;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

public class DigGoldMgr extends TempMgr {

    private static DigGoldConfig config;

    private static ActivityInfo activityInfo;

    private static RandomHelper randomHelper = new RandomHelper();

    private static int BOARD_X = 6;         //地图横向格子数

    private static int BOARD_Y = 7;         //地图纵向格子数

    @Override
    public boolean init() throws Exception {
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    public static DigGoldProto.DigGoldConfig.Builder getConfigMsg(String language) {
        if (config == null) {
            return null;
        }
        DigGoldProto.DigGoldConfig.Builder builder = DigGoldProto.DigGoldConfig.newBuilder();
        Map<Integer, DigGoldAntiqueConfig> antiqueConfigMap = config.getAntiqueConfigMap();
        for (DigGoldAntiqueConfig antiqueConfig : antiqueConfigMap.values()) {
            DigGoldProto.DigGoldAntiqueConfig.Builder antiqueBuilder = DigGoldProto.DigGoldAntiqueConfig.newBuilder();
            antiqueBuilder.setAntiqueId(antiqueConfig.getAntiqueId());
            antiqueBuilder.setIcon(antiqueConfig.getIcon());
            antiqueBuilder.setType(antiqueConfig.getType());
            antiqueBuilder.setName(ServerLanguageMgr.getContent(antiqueConfig.getName(), language));
            antiqueBuilder.setDesc(ServerLanguageMgr.getContent(antiqueConfig.getDesc(), language));
            antiqueBuilder.setValue(antiqueConfig.getValue());
            antiqueBuilder.setWeight(antiqueConfig.getWeight());
            builder.addAntiqueConfigs(antiqueBuilder);
        }

        Map<Integer, DigGoldBlockConfig> blockConfigMap = config.getBlockConfigMap();
        for (DigGoldBlockConfig blockConfig : blockConfigMap.values()) {
            DigGoldProto.DigGoldBlockConfig.Builder blockBuilder = DigGoldProto.DigGoldBlockConfig.newBuilder();
            blockBuilder.setType(blockConfig.getType());
            blockBuilder.setCostHp(blockConfig.getCostHp());
            blockBuilder.setName(ServerLanguageMgr.getContent(blockConfig.getName(), language));
            blockBuilder.setDesc(ServerLanguageMgr.getContent(blockConfig.getDesc(), language));
            builder.addBlockConfigs(blockBuilder);
        }

        Map<Integer, DigGoldMapConfig> mapConfigMap = config.getMapConfigMap();
        for (DigGoldMapConfig mapConfig : mapConfigMap.values()) {
            DigGoldProto.DigGoldMapConfig.Builder mapBuilder = DigGoldProto.DigGoldMapConfig.newBuilder();
            mapBuilder.setId(mapConfig.getId());
            mapBuilder.setType(mapConfig.getType());
            mapBuilder.setDynamiteWeight(mapConfig.getDynamiteWeight());
            mapBuilder.setDrillWeight(mapConfig.getDrillWeight());
            mapBuilder.setAntiqueWeight(mapConfig.getAntiqueWeight());
            mapBuilder.setParam(mapConfig.getParam());
            mapBuilder.setWeight(mapConfig.getWeight());
            builder.addMapConfigs(mapBuilder);
        }

        Map<Integer, DigGoldStratumConfig> stratumConfigMap = config.getStratumConfigMap();
        for (DigGoldStratumConfig stratumConfig : stratumConfigMap.values()) {
            DigGoldProto.StratumConfig.Builder stratumBuilder = DigGoldProto.StratumConfig.newBuilder();
            stratumBuilder.setId(stratumConfig.getId());
            stratumBuilder.setName(ServerLanguageMgr.getContent(stratumConfig.getName(), language));
            stratumBuilder.setUnlock(stratumConfig.getUnlock());
            stratumBuilder.setMagnification(stratumConfig.getMagnification());
            builder.addStratumConfigs(stratumBuilder);
        }

        return builder;

    }

    public static void reloadActivityData() {
        getLogger().info("reload DigGold activity start");
        List<ActivityInfo> list = NormalActivityMgr.getOpenActivityInfoList(eActivityType.DigGold.getValue());
        if (list.isEmpty()) {
            getLogger().info("no DigGold Activity in show time");
            activityInfo = null;
            config = null;
            return;
        }
        activityInfo = list.get(0);
        int activityId = activityInfo.getActivityId();
        Map<Integer, DigGoldAntiqueConfig> tmpAntiqueConfig = DigGoldBusiness.getDigGoldAntiqueConfigMap(activityId);
        Map<Integer, DigGoldBlockConfig> tmpBlockConfig = DigGoldBusiness.getDigGoldBlockConfigMap(activityId);
        Map<Integer, DigGoldMapConfig> tmpMapConfig = DigGoldBusiness.getDigGoldMapConfigMap(activityId);
        Map<Integer, DigGoldStratumConfig> tmpStratumConfig = DigGoldBusiness.getDigGoldStratumConfigMap(activityId);
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(activityId);
        DigGoldConfig digGoldConfig = new DigGoldConfig(tmpAntiqueConfig, tmpBlockConfig, tmpMapConfig, tmpStratumConfig, activityConfigMap);
        config = digGoldConfig;

        getLogger().info("reload Dig Gold end, activityId {}.", activityInfo.getActivityId());
        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            player.getModule(DigGoldModule.class).syncConfig();
            player.getModule(DigGoldModule.class).syncUserData();
        }
    }

    /**
     * 获取当前土层
     */
    public static DigGoldStratumConfig getStratum(long score) {

        Map<Integer, DigGoldStratumConfig> stratumConfigMap = config.getStratumConfigMap();
        DigGoldStratumConfig stratumConfig = stratumConfigMap.get(1);
        for (DigGoldStratumConfig digGoldStratumConfig : stratumConfigMap.values()) {
            if (digGoldStratumConfig.getId() > stratumConfig.getId() && score >= digGoldStratumConfig.getUnlock()) {
                stratumConfig = digGoldStratumConfig;
            }
        }
        return stratumConfig;
    }


    public static void main(String[] args) {
        List<DigGoldBlockData> digGoldUpBlockData = generateRandomMapData(0);
        List<DigGoldBlockData> digGoldDownBlockData = generateRandomMapData(1);
        digGoldUpBlockData.addAll(digGoldDownBlockData);
        printBlock(digGoldUpBlockData);


    }


    private static void printBlock(List<DigGoldBlockData> data) {
        DigGoldModule.sortBlock(data);

    }


    public static List<DigGoldBlockData> generateRandomMapData(int mapIndex) {
        List<DigGoldBlockData> blockDataList = new ArrayList<>();
        for (int j = mapIndex * BOARD_Y; j < (mapIndex + 1) * BOARD_Y; j++) {
            for (int i = 0; i < BOARD_X; i++) {
                {
                    DigGoldBlockData blockData = new DigGoldBlockData();
                    blockData.setX(i);
                    blockData.setY(j);
                    blockData.setType(randomHelper.next(0, 3));
                    blockData.setHp(randomHelper.next(1, 3));
                    blockData.setMap(mapIndex);
                    blockData.setReward(0);
                    blockDataList.add(blockData);
                }
            }
        }
        return blockDataList;
    }

    public static List<Integer> getBoxMapByIndex(boolean isPalace) {
        if (isPalace){
            List<Integer> boxList = new ArrayList<>();
            for (int boxIndex = 0;boxIndex<config.getBoxNumPerPalace();boxIndex++){
                boxList.add(boxIndex);
            }
            return boxList;
        }
        return new ArrayList<>();
    }

    public static List<DigGoldBlockData> getMapByIndex(int mapIndex, DigGoldUserData userData) {
        DigGoldMapConfig randomMap = null;

        if(mapIndex == 0){
            randomMap = getRandomMap(4);
            if (randomMap == null) {
                getLogger().error("digGold activityId{} getRandomMap error mapType={}", activityInfo.getActivityId(), 4);
                return null;
            }
        }else if(mapIndex == 1){
            randomMap = getRandomMap(5);
            if (randomMap == null) {
                getLogger().error("digGold activityId{} getRandomMap error mapType={}", activityInfo.getActivityId(), 5);
                return null;
            }
        } else if (mapIndex == 2) {
            randomMap = getRandomMap(6);
            if (randomMap == null) {
                getLogger().error("digGold activityId{} getRandomMap error mapType={}", activityInfo.getActivityId(), 6);
                return null;
            }
        } else if (mapIndex == 3){
            randomMap = getRandomMap(7);
            if (randomMap == null) {
                getLogger().error("digGold activityId{} getRandomMap error mapType={}", activityInfo.getActivityId(), 7);
                return null;
            }
        } else {
            int mapType = 0;
            if (userData.getNoPalaceTime()>=config.getDigGoldGuarantees()){
                mapType = 3;
            } else {
                DigGoldStratumConfig stratum = getStratum(userData.getScore());
                if (stratum == null) {
                    getLogger().error("digGold activityId{} getStratum error score={}", activityInfo.getActivityId(), userData.getScore());
                    return null;
                }
                Map<Integer, Integer> mapRateMap = stratum.getMapRateMap();
                if (mapRateMap == null) {
                    getLogger().error("digGold activityId{} getStratum error score={}", activityInfo.getActivityId(), userData.getScore());
                    return null;
                }
                mapType = WeightHelper.getRandomValue(mapRateMap);
            }
            randomMap = getRandomMap(mapType);
            if (randomMap == null) {
                getLogger().error("digGold activityId{} getRandomMap error mapType={}", activityInfo.getActivityId(), mapType);
                return null;
            }
        }

        return mapConfigToBlock(mapIndex, randomMap);

    }

    /**
     * 将配置转换成地图
     *
     * @return
     */

    public static List<DigGoldBlockData> mapConfigToBlock(int mapIndex, DigGoldMapConfig mapConfig) {
        List<DigGoldBlockData> blockDataList = new ArrayList<>();
        String param = mapConfig.getParam();

        List<Integer> typeList = StringUtils.stringToIntegerList(param, ",");
        int count = 0;
        for (int index : typeList) {
            //拿出方块的配置
            DigGoldBlockConfig blockConfig = config.getBlockConfigMap().get(index);
            //初始化方块
            DigGoldBlockData blockData = new DigGoldBlockData();
            int x = count % BOARD_X;
            blockData.setX(x);
            int y = mapIndex * getBoardY() + count / BOARD_X;
            blockData.setY(y);
            blockData.setType(blockConfig.getType());
            blockData.setHp(blockConfig.getCostHp());
            blockData.setMap(mapIndex);
            blockData.setReward(0);
            //第一行一定是联通
            if(y == 0){
                blockData.setLinkTop(true);
            } else {
                blockData.setLinkTop(false);
            }
            count = count + 1;
            blockDataList.add(blockData);
        }
        //随机古董数量
        int indexByWeight = randomHelper.getSafeRandomIndexByWeight(mapConfig.getAntiqueWeightList());
        String s = mapConfig.getAntiqueNumList().get(indexByWeight);    //0;1;2;4
        List<Integer> integerList = StringUtils.stringToIntegerList(s, ";");

        addRewardToBlock(eDigGoldRewardType.antique1, integerList.get(0), blockDataList);
        addRewardToBlock(eDigGoldRewardType.antique2, integerList.get(1), blockDataList);
        addRewardToBlock(eDigGoldRewardType.antique3, integerList.get(2), blockDataList);
        addRewardToBlock(eDigGoldRewardType.antique4, integerList.get(3), blockDataList);

        //随机钻头数量
        int drillNum = 0;
        NormalWeightItem randomResult = WeightHelper.getRandomResult(mapConfig.getDrillWeightList());
        if (randomResult != null) {
            drillNum = randomResult.getValue().intValue();
        }
        addRewardToBlock(eDigGoldRewardType.drill, drillNum, blockDataList);
        //随机炸弹数量
        int bombNum = 0;
        NormalWeightItem randomResult1 = WeightHelper.getRandomResult(mapConfig.getDynamiteWeightList());
        if (randomResult1 != null) {
            bombNum = randomResult1.getValue().intValue();
        }
        addRewardToBlock(eDigGoldRewardType.dynamite, bombNum, blockDataList);
        //随机铲子数量
        int shovelNum = 0;
        NormalWeightItem randomResult2 = WeightHelper.getRandomResult(mapConfig.getShovelWeightList());
        if (randomResult2 != null) {
            shovelNum = randomResult2.getValue().intValue();
        }
        addRewardToBlock(eDigGoldRewardType.shovel, shovelNum, blockDataList);

        sortBlock(blockDataList);
        return blockDataList;

    }

    public static void sortBlock(List<DigGoldBlockData> blockDataList) {
        blockDataList.sort(new Comparator<DigGoldBlockData>() {
            @Override
            public int compare(DigGoldBlockData o1, DigGoldBlockData o2) {
                if (o1.getY() < o2.getY()) {
                    return -1;
                } else if (o1.getY() > o2.getY()) {
                    return 1;
                } else {
                    return Integer.compare(o1.getX(), o2.getX());
                }
            }
        });
    }

    /**
     * 往泥巴里加奖励
     */
    public static void addRewardToBlock(eDigGoldRewardType rewardType, int rewardNum, List<DigGoldBlockData> blockDataList) {
        if (blockDataList == null || blockDataList.isEmpty()) {
            return;
        }
        List<DigGoldBlockData> canAddList = new ArrayList<>();
        for (DigGoldBlockData blockData : blockDataList) {
            if (blockData.getType() == eDigGoldBlockType.mud.getValue() && blockData.getReward() == 0) {
                canAddList.add(blockData);
            }
        }
        if (canAddList.isEmpty()) {
            return;
        }

        randomHelper.shuffleList(canAddList);
        if (rewardNum > canAddList.size()) {
            rewardNum = canAddList.size();
        }

        for (int i = 0; i < rewardNum; i++) {
            DigGoldBlockData digGoldBlockData = canAddList.get(i);
            int reward = getRewardByType(rewardType);
            digGoldBlockData.setReward(reward);
        }


    }

    /**
     * 随机获取某个类型的奖励
     */
    public static int getRewardByType(eDigGoldRewardType rewardType) {
        if (rewardType == eDigGoldRewardType.drill) {
            return config.getDrillItemId();
        }
        if (rewardType == eDigGoldRewardType.dynamite) {
            return config.getBombItemId();
        }
        if (rewardType == eDigGoldRewardType.antique1) {
            Map<Integer, Map<Integer, Integer>> antiqueWeightMap = config.getAntiqueWeightMap();
            if (antiqueWeightMap == null || antiqueWeightMap.isEmpty()) {
                return 0;
            }
            Map<Integer, Integer> integerIntegerMap = antiqueWeightMap.get(1);
            if (integerIntegerMap == null || integerIntegerMap.isEmpty()) {
                return 0;
            }
            return WeightHelper.getRandomValue(integerIntegerMap);
        }

        if (rewardType == eDigGoldRewardType.antique2) {
            Map<Integer, Map<Integer, Integer>> antiqueWeightMap = config.getAntiqueWeightMap();
            if (antiqueWeightMap == null || antiqueWeightMap.isEmpty()) {
                return 0;
            }
            Map<Integer, Integer> integerIntegerMap = antiqueWeightMap.get(2);
            if (integerIntegerMap == null || integerIntegerMap.isEmpty()) {
                return 0;
            }
            return WeightHelper.getRandomValue(integerIntegerMap);
        }

        if (rewardType == eDigGoldRewardType.antique3) {
            Map<Integer, Map<Integer, Integer>> antiqueWeightMap = config.getAntiqueWeightMap();
            if (antiqueWeightMap == null || antiqueWeightMap.isEmpty()) {
                return 0;
            }
            Map<Integer, Integer> integerIntegerMap = antiqueWeightMap.get(3);
            if (integerIntegerMap == null || integerIntegerMap.isEmpty()) {
                return 0;
            }
            return WeightHelper.getRandomValue(integerIntegerMap);
        }

        if (rewardType == eDigGoldRewardType.antique4) {
            Map<Integer, Map<Integer, Integer>> antiqueWeightMap = config.getAntiqueWeightMap();
            if (antiqueWeightMap == null || antiqueWeightMap.isEmpty()) {
                return 0;
            }
            Map<Integer, Integer> integerIntegerMap = antiqueWeightMap.get(4);
            if (integerIntegerMap == null || integerIntegerMap.isEmpty()) {
                return 0;
            }
            return WeightHelper.getRandomValue(integerIntegerMap);
        }
        if (rewardType == eDigGoldRewardType.shovel) {
            return config.getDigItemId();
        }

        return 0;
    }


    /**
     * 获取随机一个地图
     *
     * @param type
     * @return
     */
    public static DigGoldMapConfig getRandomMap(int type) {
        if (config == null) {
            return null;
        }
        Map<Integer, List<NormalWeightItem>> mapWeightMap = config.getMapWeightMap();
        if (mapWeightMap == null || mapWeightMap.isEmpty()) {
            return null;
        }
        if (!mapWeightMap.containsKey(type)) {
            return null;
        }
        List<NormalWeightItem> normalWeightItems = mapWeightMap.get(type);
        if (normalWeightItems == null || normalWeightItems.isEmpty()) {
            return null;
        }
        BigInteger randomValue = WeightHelper.getRandomValue(normalWeightItems);
        Map<Integer, DigGoldMapConfig> mapConfigMap = config.getMapConfigMap();
        if (mapConfigMap == null || !mapConfigMap.containsKey(randomValue.intValue())) {
            return null;
        }

        return mapConfigMap.get(randomValue.intValue());
    }

    public static DigGoldStratumConfig getStratumConfigById(int stratumId) {
        Map<Integer, DigGoldStratumConfig> stratumConfigMap = config.getStratumConfigMap();
        if (stratumConfigMap == null || !stratumConfigMap.containsKey(stratumId)) {
            return null;
        }
        return stratumConfigMap.get(stratumId);
    }

    public static DigGoldAntiqueConfig getDigGoldAntiqueConfigById(int antiqueId) {
        return config.getAntiqueConfigMap().get(antiqueId);
    }

    public static BigInteger getRandomShovelRewardNum(){
        List<NormalWeightItem> randomShovelNumList = config.getRandomShovelNumList();
        if (randomShovelNumList == null || randomShovelNumList.isEmpty()) {
            return BigInteger.ONE;
        }
        BigInteger randomValue = WeightHelper.getRandomValue(randomShovelNumList);
        return randomValue;
    }

    public static int getBoardX() {
        return BOARD_X;
    }

    public static int getBoardY() {
        return BOARD_Y;
    }

    public static DigGoldConfig getConfig() {
        return config;
    }

    public static ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public static RandomHelper getRandomHelper() {
        return randomHelper;
    }


}
